package com.vivid.system.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.vivid.system.domain.Model;
import com.vivid.system.service.IModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 模型表Controller
 *
 * @author vivid
 * @date 2022-08-09
 */
@CrossOrigin
@RestController
@RequestMapping("/system/model")
public class ModelController extends BaseController {
    @Autowired
    private IModelService modelService;
    @Autowired
    private ToolController toolController;

    private Model model;
    private File file;
    private String txtPath;
    /**
     * 查询模型表列表
     */
    @PreAuthorize("@ss.hasPermi('system:model:list')")
    @GetMapping("/list")
    public TableDataInfo list(Model model) {
        List<Model> list = modelService.selectModelList(model);
        return getDataTable(list);
    }

    /**
     * 导出模型表列表
     */
    @PreAuthorize("@ss.hasPermi('system:model:export')")
    @Log(title = "模型表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Model model) {
        List<Model> list = modelService.selectModelList(model);
        ExcelUtil<Model> util = new ExcelUtil<Model>(Model.class);
        util.exportExcel(response, list, "模型表数据");
    }

    /**
     * 获取模型表详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:model:query')")
    @GetMapping(value = "/{modelId}")
    public AjaxResult getInfo(@PathVariable("modelId") Long modelId) {
        return AjaxResult.success(modelService.selectModelByModelId(modelId));
    }
    /**
     * 查询模型名，确保模型名的唯一性
     */
    @PostMapping("/getModelName")
    public AjaxResult getModelName(@RequestParam String modelName) {
        if(modelService.selectModelByModelName(modelName)!=null){
           return AjaxResult.error("模型名重复");
        }
        return AjaxResult.success("模型名未重复");
    }

    /**
     * 新增模型表
     */
    @PreAuthorize("@ss.hasPermi('system:model:add')")
    @Log(title = "模型表", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Model model) {
        return toAjax(modelService.insertModel(model));
    }

    /**
     * 修改模型表
     */
    @PreAuthorize("@ss.hasPermi('system:model:edit')")
    @Log(title = "模型表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Model model) {
        return toAjax(modelService.updateModel(model));
    }

    /**
     * 删除模型表
     */
    @PreAuthorize("@ss.hasPermi('system:model:remove')")
    @Log(title = "模型表", businessType = BusinessType.DELETE)
    @DeleteMapping("/{modelIds}")
    public AjaxResult remove(@PathVariable Long[] modelIds) {
        return toAjax(modelService.deleteModelByModelIds(modelIds));
    }
    /**
     * 接收上传的文件
     * 将MultipartFile转换为File
     * @param file
     * @return
     */
    @PostMapping("/file")
    public AjaxResult MultipartFile(MultipartFile file) {
        //判断是否为null
        if (file.equals("") || file.getSize() <= 0) {
            return AjaxResult.error("文件为空，请重新上传！");
        }
        this.file = toolController.MultipartFile(file);
        return AjaxResult.success("上传成功！");
    }

    /**
     * 接收建模的参数(接收训练数据文件在另一个接口)
     * 目的：将建模输入框里的数据和训练数据文件的本地路径传给python程序
     * return 分别为 最佳适应度、函数表达式、均方根误差、拟合曲线.txt文件绝对路径、拟合模型绝对路径的list
     */
    @PostMapping("/train")
    public AjaxResult train(@RequestBody String trains[]) {
//        for(String s:trains){
//            System.out.println("训练字段"+s);
//        }

        List returnList = new ArrayList();
        model = new Model();
        String path = this.file.getAbsolutePath();//获取绝对路径
        String[] result = new String[19];
        result[0] = "python";
        result[1] = "python-code\\train.py";
        result[18] = path;//上传文件的绝对路径
        toolController.existFile(trains[16]);//判断文件路径是否存在
        int i = 2;
        for (String param : trains) {//模型名和文件存放路径拼接
            if (i == 18) {
                result[i - 1] = param + "\\" + result[i - 1];
            } else {
                result[i] = param;
            }
            i++;
        }
        try {
            Process proc = Runtime.getRuntime().exec(result);// 执行py文件
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(),"gb2312"));
            String line = null;
            int a = 0;
            while ((line = in.readLine()) != null) {
                returnList.add(line);
                if(a==3){
                    txtPath = line;
                }
                if(a==4){
                    model.setModelPath(line);
                }
                a++;
                //返回的参数依次是：最佳适应度、函数表达式、均方根误差、拟合曲线.txt文件绝对路径、拟合模型绝对路径
            }
            model.setModelName(trains[15]);
            modelService.insertModel(model);
            in.close();
            proc.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            return AjaxResult.error("建模失败，请检查上传参数！");
        }
        return AjaxResult.success("建模成功！",returnList);
    }

    /**
     * return 建模生成的txt文件的值
     */
    @GetMapping("/returnTrainTxt")
    public List<List<Float>>returnTrainTxt(){
       return toolController.readTxt(txtPath);
    }



}
